﻿param($config,$int,$URL,[switch]$debug,[switch]$nopost,[switch]$tofile,[switch]$toscreen)


if(!$URL) { write "Need VCOPs HTTPPostAdapter URL"; exit;}
if(!$config) { write "Need to define config file"; exit;}
$interval = 5
if($int) { $interval = $int}

$path = (Split-Path -parent $MyInvocation.MyCommand.Definition)
Set-Location $path
$global:textMetrics = ""
$global:ArrMetrics = @()

function isNumeric ($x) {
    try {
        0 + $x | Out-Null
        return $true
    } catch {
        return $false
    }
}
function convertDataToHashTable($data) {
	#Now convert to table
	$temptable = @{}
	foreach ($line in $data) {
		#Make sure we only get stat lines
		if ($line -notmatch "EMCOEforBlock" -and $line.length -gt 5) {
			$me = $line.split(",")
			$temptable.Add($me[0],$me[4])
		}
	}

	return $temptable
}
function loadPrevStatFile($vnxName) {
	$filename = "vnxstate." + $vnxName.Replace(":","_") + ".tmp"
	Set-Location $path
	$infile = Get-Content $filename 
	$StatTable = convertDataToHashTable $infile
	return $StatTable
}
function sendPost($text){
	$parameters = @"
$text
"@
	$http_request = New-Object -ComObject Msxml2.XMLHTTP
	$http_request.open('POST', $URL, $false)
	$http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded")
	$http_request.setRequestHeader("Content-length", $parameters.length)
	$http_request.setRequestHeader("Connection", "close")
	$http_request.send($parameters)
	$http_request.statusText
	return $http_request.responseText
}
function runDataCollection($spaip, $spbip, $username, $password, $scope){
    $auth = "-username $username -password $password -scope $scope"
	#Write-Progress -Activity "VNX to vCops Enterprise Statistics Posting" -CurrentOperation "Array Data Post" -Status "Collecting Data from Array" -PercentComplete 1
	get-job | stop-job 
    get-job | remove-job -force
    $spajob = {
                set-location $args[0];
                $cmd = "&'.\get_naviseccli.ps1' -spip "+$args[1]+" "+$args[2]+" -get sp -getpkey 'Storage Processor'"; invoke-expression $cmd
                }    
    $spbjob = {
                set-location $args[0];
                $cmd = "&'.\get_naviseccli.ps1' -spip "+$args[1]+" "+$args[2]+" -get sp -getpkey 'Storage Processor'"; invoke-expression $cmd
                }
    $lunjob = {
                set-location $args[0];
                $cmd = "&'.\get_naviseccli.ps1' -spip "+$args[1]+" "+$args[2]+" -get lun -getpkey 'name' "+$args[3]; invoke-expression $cmd
                }
    $cachejob = {
                set-location $args[0];
                $cmd = "&'.\get_naviseccli.ps1' -spip "+$args[1]+" "+$args[2]+" -get cache "+$args[3]; invoke-expression $cmd
                }	
	$fastcachejob = {
                set-location $args[0];
                $cmd = "&'.\get_naviseccli.ps1' -spip "+$args[1]+" "+$args[2]+" -get fastcache "+$args[3]; invoke-expression $cmd
                }
				
	$diskjob = {
                set-location $args[0];
                $cmd = "&'.\get_naviseccli.ps1' -spip "+$args[1]+" "+$args[2]+" -get disk "+$args[3]; invoke-expression $cmd
                }

	$rgjob = {
                set-location $args[0];
                $cmd = "&'.\get_naviseccli.ps1' -spip "+$args[1]+" "+$args[2]+" -get rg -getpkey 'RaidGroup ID' "+$args[3]; invoke-expression $cmd
                }
	
    start-job -argumentlist $path, $spaip, $auth, $engmode -name SPA $spajob | out-null
    start-job -argumentlist $path, $spbip, $auth, $engmode -name SPB $spbjob | out-null
    start-job -argumentlist $path, $spaip, $auth, $engmode -name LUN $lunjob | out-null
    start-job -argumentlist $path, $spaip, $auth, $engmode -name CACHE $cachejob | out-null
	start-job -argumentlist $path, $spaip, $auth, $engmode -name FASTCACHE $fastcachejob | out-null
	start-job -argumentlist $path, $spaip, $auth, $engmode -name DISK $diskjob | out-null
	start-job -argumentlist $path, $spaip, $auth, $engmode -name RAIDGROUP $rgjob | out-null
	
    $count=1
    do {
    	$count++
    	sleep 1
    }
    while ((get-job | where {$_.State -ne 'Completed'}) -and ($count -lt 40))
    #write "slept $count seconds"
    if ($count -eq 40) {
        get-job | where {$_.State -ne 'Completed'} | stop-job
        write "quit becuase it took too long"
        exit
    }
    $allstats = @{}
	foreach ($job in Get-Job) {
		[array]$joboutput = $job | Receive-Job
		$allstats[$job.Name] = $joboutput
	}

	return $allstats
}
function AddStat($statName,$statValue) {
	$date = [math]::round(([decimal]((get-date).ToUniversalTime() | Get-Date -UFormat "%s")*1000),0)
	if ($statValue.length -eq 0) {$statValue = "N/A"}
	$statLine = "$statName,0,NoValue,$date,$statValue"
	$global:ArrMetrics +=  $statLine
	$global:textMetrics = $global:textMetrics + @"
$statName,0,NoValue,$date,$statValue

"@
}
function AddStatHeader($sectionName,$resourceKindKey,$resourceDescription) {
	$global:textMetrics += @"
$sectionName,$resourceKindKey,$resourceDescription,$interval

"@
}
function getArrayName($arrayInfo) {
	$auth = "-username " + $arrayInfo['username'] + " -password " + $arrayInfo['password'] + " -scope " + $arrayInfo['scope']
	Set-Location $path
	get-job | stop-job 
    get-job | remove-job -force
    $namejob = {
                set-location $args[0];
                $cmd = "&'.\get_naviseccli.ps1' -spip "+$args[1]+" "+$args[2]+" -get array"; invoke-expression $cmd
                }   
	start-job -argumentlist $path, $arrayInfo["SPAIP"], $auth, $engmode -name ArrayName $namejob | out-null
	 $count=1
    do {
    	$count++
    	sleep 1
    }
    while ((get-job | where {$_.State -ne 'Completed'}) -and ($count -lt 40))
    #write "slept $count seconds"
    if ($count -eq 40) {
        get-job | where {$_.State -ne 'Completed'} | stop-job
        write "quit becuase it took too long"
        exit
    }
	$joboutput = Get-Job -Name "ArrayName" | Receive-Job
	$arrayname = $joboutput["Array Name"] + "-" + $joboutput["SPA                                     50"]
	return $arrayname
}
function getArrayList() {
	$inifile = Get-Content $config
	$arrayList = @()
	$i = 0
	foreach ($line in $inifile) {
		if ($line -notmatch "^#") {
			$thisarray = @{}
			$data = $line.Split()
			$thisarray.Add("Name",$data[0])
			$thisarray.Add("SPAIP",$data[1])
			$thisarray.Add("SPBIP",$data[2])
			$thisarray.Add("username",$data[3])
			$thisarray.Add("password",$data[4])
			$thisarray.Add("scope",$data[5])
			$arrayList += $thisarray
		}
	}
	return $arrayList
}
function compareCurrentAndPrev($currentText, $arrayName) {
	$currentTable = convertDataToHashTable($global:ArrMetrics)
	$previousTable = loadPrevStatFile($arrayName)
	foreach ($statkey in $currentTable.Keys) {
		#For each one of the metrics, we need to check if the metric is numeric 
		#(otherwise theres no point in doing a gauge on it) and if the metric appears in the previous table
		#(maybe its a new metric).  We also need to make sure we aren't evaluating a delta metric itself (doesn't make sense to compare them - its like a second derviative for storage)
		if (!$statkey.EndsWith("perSecond") -and (isNumeric($currentTable[$statkey])) -and $previousTable.containsKey($statkey)) {
			#Its numeric and exists in the other table, so lets compare them.
			$curVal = $currentTable[$statkey]
			$preVal = $previousTable[$statkey]
			$rawdelta = $curVal - $preVal
			$persecond = $rawdelta / ($interval * 60)
			$newStatName = $statkey + "_perSecond"
			AddStat -statName $newStatName -statValue $persecond
		}
	}
}
function getAndSubmitAndSaveDataForArray($arrayInfo) {
	$arrayName = getArrayName $arrayInfo
	$global:textMetrics = ""
	$global:ArrMetrics = @()
	$allstats = runDataCollection $arrayInfo["SPAIP"] $arrayInfo["SPBIP"] $arrayInfo["username"] $arrayInfo["password"] $arrayInfo["scope"]
	#For each of the resources in the stats set (SPs & LUNs)
 	#Write-Progress -Activity "VNX to vCops Enterprise Statistics Posting" -Status "Processing Array Data" -PercentComplete 2
	$count = 0
	AddStatHeader $arrayName "EMCOEforBlock" "None"
	foreach ($resourceType in $allstats.Keys) {
		$metricprefix = $resourceType + "|"
		$stats = $allstats[$resourceType][0]
		if ($stats.Count -eq 1 -and $resourceType -notmatch "^SP") {
			$stats = $stats[0]
		}
		foreach ($metricname in $stats.Keys) {
			$fullmetricname = $metricprefix + $metricname
			$metricvals = $stats[$metricname]
			if ($metricvals -is [System.Collections.Hashtable]) {
				foreach ($metric in $metricvals.Keys) {
					$newmetricname = $fullmetricname + "|" + $metric
					$metricval = $metricvals[$metric]
					AddStat -statName $newmetricname -statValue $metricval
				}
			}
			else {
				AddStat -statName $fullmetricname -statValue $metricvals
			}
		}
	}

	compareCurrentAndPrev $global:textMetrics $arrayname	
	if ($toscreen) {
		Write $global:textMetrics
	}
	if ($tofile) {
		Set-Location $path
		$outfilename = "vnxstate." + $arrayname.Replace(":","_") + ".tmp"
		$global:textMetrics | Out-File -FilePath $outfilename
	}
	if (!$nopost) {sendPost $global:textMetrics } else {Write "Not Posting Data in nopost mode"}

}


while($true) {
	$arrayList = getArrayList
	$startTime = [math]::round(([decimal]((get-date).ToUniversalTime() | Get-Date -UFormat "%s")*1000),0)
	foreach ($arrayInfo in $arrayList) {
		getAndSubmitandSaveDataForArray $arrayInfo
	}
	$endTime = [math]::round(([decimal]((get-date).ToUniversalTime() | Get-Date -UFormat "%s")*1000),0)
	$runtime = ($endTime-$startTime) / 1000
	Write (Get-Date) ": Ran for $runtime seconds"
	sleep ($interval * 60)
}